<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><style>@font-face {
  font-family: octicons-anchor;
  src: url(https://cdnjs.cloudflare.com/ajax/libs/octicons/4.4.0/font/octicons.woff) format('woff');
}

* {
    box-sizing: border-box;
}

body {
    width: 980px;
    margin-right: auto;
    margin-left: auto;
    color:#333;
    background:#fff;
}

body .markdown-body {
    padding: 45px;
    border: 1px solid #ddd;
    border-radius: 3px;
    word-wrap: break-word;
}

pre {
    font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace;
}

.markdown-body {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  color: #333;
  font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  font-size: 16px;
  line-height: 1.6;
  word-wrap: break-word;
}

.markdown-body a {
  background-color: transparent;
}

.markdown-body a:active,
.markdown-body a:hover {
  outline: 0;
}

.markdown-body strong {
  font-weight: bold;
}

.markdown-body h1 {
  font-size: 2em;
  margin: 0.67em 0;
}

.markdown-body img {
  border: 0;
}

.markdown-body hr {
  box-sizing: content-box;
  height: 0;
}

.markdown-body pre {
  overflow: auto;
}

.markdown-body code,
.markdown-body kbd,
.markdown-body pre {
  font-family: monospace, monospace;
  font-size: 1em;
}

.markdown-body input {
  color: inherit;
  font: inherit;
  margin: 0;
}

.markdown-body html input[disabled] {
  cursor: default;
}

.markdown-body input {
  line-height: normal;
}

.markdown-body input[type="checkbox"] {
  box-sizing: border-box;
  padding: 0;
}

.markdown-body table {
  border-collapse: collapse;
  border-spacing: 0;
}

.markdown-body td,
.markdown-body th {
  padding: 0;
}

.markdown-body input {
  font: 13px / 1.4 Helvetica, arial, nimbussansl, liberationsans, freesans, clean, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}

.markdown-body a {
  color: #4078c0;
  text-decoration: none;
}

.markdown-body a:hover,
.markdown-body a:active {
  text-decoration: underline;
}

.markdown-body hr {
  height: 0;
  margin: 15px 0;
  overflow: hidden;
  background: transparent;
  border: 0;
  border-bottom: 1px solid #ddd;
}

.markdown-body hr:before {
  display: table;
  content: "";
}

.markdown-body hr:after {
  display: table;
  clear: both;
  content: "";
}

.markdown-body h1,
.markdown-body h2,
.markdown-body h3,
.markdown-body h4,
.markdown-body h5,
.markdown-body h6 {
  margin-top: 15px;
  margin-bottom: 15px;
  line-height: 1.1;
}

.markdown-body h1 {
  font-size: 30px;
}

.markdown-body h2 {
  font-size: 21px;
}

.markdown-body h3 {
  font-size: 16px;
}

.markdown-body h4 {
  font-size: 14px;
}

.markdown-body h5 {
  font-size: 12px;
}

.markdown-body h6 {
  font-size: 11px;
}

.markdown-body blockquote {
  margin: 0;
}

.markdown-body ul,
.markdown-body ol {
  padding: 0;
  margin-top: 0;
  margin-bottom: 0;
}

.markdown-body ol ol,
.markdown-body ul ol {
  list-style-type: lower-roman;
}

.markdown-body ul ul ol,
.markdown-body ul ol ol,
.markdown-body ol ul ol,
.markdown-body ol ol ol {
  list-style-type: lower-alpha;
}

.markdown-body dd {
  margin-left: 0;
}

.markdown-body code {
  font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
  font-size: 12px;
}

.markdown-body pre {
  margin-top: 0;
  margin-bottom: 0;
  font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace;
}

.markdown-body .select::-ms-expand {
  opacity: 0;
}

.markdown-body .octicon {
  font: normal normal normal 16px/1 octicons-anchor;
  display: inline-block;
  text-decoration: none;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

.markdown-body .octicon-link:before {
  content: '\f05c';
}

.markdown-body:before {
  display: table;
  content: "";
}

.markdown-body:after {
  display: table;
  clear: both;
  content: "";
}

.markdown-body>*:first-child {
  margin-top: 0 !important;
}

.markdown-body>*:last-child {
  margin-bottom: 0 !important;
}

.markdown-body a:not([href]) {
  color: inherit;
  text-decoration: none;
}

.markdown-body .anchor {
  display: inline-block;
  padding-right: 2px;
  margin-left: -18px;
}

.markdown-body .anchor:focus {
  outline: none;
}

.markdown-body h1,
.markdown-body h2,
.markdown-body h3,
.markdown-body h4,
.markdown-body h5,
.markdown-body h6 {
  margin-top: 1em;
  margin-bottom: 16px;
  font-weight: bold;
  line-height: 1.4;
}

.markdown-body h1 .octicon-link,
.markdown-body h2 .octicon-link,
.markdown-body h3 .octicon-link,
.markdown-body h4 .octicon-link,
.markdown-body h5 .octicon-link,
.markdown-body h6 .octicon-link {
  color: #000;
  vertical-align: middle;
  visibility: hidden;
}

.markdown-body h1:hover .anchor,
.markdown-body h2:hover .anchor,
.markdown-body h3:hover .anchor,
.markdown-body h4:hover .anchor,
.markdown-body h5:hover .anchor,
.markdown-body h6:hover .anchor {
  text-decoration: none;
}

.markdown-body h1:hover .anchor .octicon-link,
.markdown-body h2:hover .anchor .octicon-link,
.markdown-body h3:hover .anchor .octicon-link,
.markdown-body h4:hover .anchor .octicon-link,
.markdown-body h5:hover .anchor .octicon-link,
.markdown-body h6:hover .anchor .octicon-link {
  visibility: visible;
}

.markdown-body h1 {
  padding-bottom: 0.3em;
  font-size: 2.25em;
  line-height: 1.2;
  border-bottom: 1px solid #eee;
}

.markdown-body h1 .anchor {
  line-height: 1;
}

.markdown-body h2 {
  padding-bottom: 0.3em;
  font-size: 1.75em;
  line-height: 1.225;
  border-bottom: 1px solid #eee;
}

.markdown-body h2 .anchor {
  line-height: 1;
}

.markdown-body h3 {
  font-size: 1.5em;
  line-height: 1.43;
}

.markdown-body h3 .anchor {
  line-height: 1.2;
}

.markdown-body h4 {
  font-size: 1.25em;
}

.markdown-body h4 .anchor {
  line-height: 1.2;
}

.markdown-body h5 {
  font-size: 1em;
}

.markdown-body h5 .anchor {
  line-height: 1.1;
}

.markdown-body h6 {
  font-size: 1em;
  color: #777;
}

.markdown-body h6 .anchor {
  line-height: 1.1;
}

.markdown-body p,
.markdown-body blockquote,
.markdown-body ul,
.markdown-body ol,
.markdown-body dl,
.markdown-body table,
.markdown-body pre {
  margin-top: 0;
  margin-bottom: 16px;
}

.markdown-body hr {
  height: 4px;
  padding: 0;
  margin: 16px 0;
  background-color: #e7e7e7;
  border: 0 none;
}

.markdown-body ul,
.markdown-body ol {
  padding-left: 2em;
}

.markdown-body ul ul,
.markdown-body ul ol,
.markdown-body ol ol,
.markdown-body ol ul {
  margin-top: 0;
  margin-bottom: 0;
}

.markdown-body li>p {
  margin-top: 16px;
}

.markdown-body dl {
  padding: 0;
}

.markdown-body dl dt {
  padding: 0;
  margin-top: 16px;
  font-size: 1em;
  font-style: italic;
  font-weight: bold;
}

.markdown-body dl dd {
  padding: 0 16px;
  margin-bottom: 16px;
}

.markdown-body blockquote {
  padding: 0 15px;
  color: #777;
  border-left: 4px solid #ddd;
}

.markdown-body blockquote>:first-child {
  margin-top: 0;
}

.markdown-body blockquote>:last-child {
  margin-bottom: 0;
}

.markdown-body table {
  display: block;
  width: 100%;
  overflow: auto;
  word-break: normal;
  word-break: keep-all;
}

.markdown-body table th {
  font-weight: bold;
}

.markdown-body table th,
.markdown-body table td {
  padding: 6px 13px;
  border: 1px solid #ddd;
}

.markdown-body table tr {
  background-color: #fff;
  border-top: 1px solid #ccc;
}

.markdown-body table tr:nth-child(2n) {
  background-color: #f8f8f8;
}

.markdown-body img {
  max-width: 100%;
  box-sizing: content-box;
  background-color: #fff;
}

.markdown-body code {
  padding: 0;
  padding-top: 0.2em;
  padding-bottom: 0.2em;
  margin: 0;
  font-size: 85%;
  background-color: rgba(0,0,0,0.04);
  border-radius: 3px;
}

.markdown-body code:before,
.markdown-body code:after {
  letter-spacing: -0.2em;
  content: "\00a0";
}

.markdown-body pre>code {
  padding: 0;
  margin: 0;
  font-size: 100%;
  word-break: normal;
  white-space: pre;
  background: transparent;
  border: 0;
}

.markdown-body .highlight {
  margin-bottom: 16px;
}

.markdown-body .highlight pre,
.markdown-body pre {
  padding: 16px;
  overflow: auto;
  font-size: 85%;
  line-height: 1.45;
  background-color: #f7f7f7;
  border-radius: 3px;
}

.markdown-body .highlight pre {
  margin-bottom: 0;
  word-break: normal;
}

.markdown-body pre {
  word-wrap: normal;
}

.markdown-body pre code {
  display: inline;
  max-width: initial;
  padding: 0;
  margin: 0;
  overflow: initial;
  line-height: inherit;
  word-wrap: normal;
  background-color: transparent;
  border: 0;
}

.markdown-body pre code:before,
.markdown-body pre code:after {
  content: normal;
}

.markdown-body kbd {
  display: inline-block;
  padding: 3px 5px;
  font-size: 11px;
  line-height: 10px;
  color: #555;
  vertical-align: middle;
  background-color: #fcfcfc;
  border: solid 1px #ccc;
  border-bottom-color: #bbb;
  border-radius: 3px;
  box-shadow: inset 0 -1px 0 #bbb;
}

.markdown-body .pl-c {
  color: #969896;
}

.markdown-body .pl-c1,
.markdown-body .pl-s .pl-v {
  color: #0086b3;
}

.markdown-body .pl-e,
.markdown-body .pl-en {
  color: #795da3;
}

.markdown-body .pl-s .pl-s1,
.markdown-body .pl-smi {
  color: #333;
}

.markdown-body .pl-ent {
  color: #63a35c;
}

.markdown-body .pl-k {
  color: #a71d5d;
}

.markdown-body .pl-pds,
.markdown-body .pl-s,
.markdown-body .pl-s .pl-pse .pl-s1,
.markdown-body .pl-sr,
.markdown-body .pl-sr .pl-cce,
.markdown-body .pl-sr .pl-sra,
.markdown-body .pl-sr .pl-sre {
  color: #183691;
}

.markdown-body .pl-v {
  color: #ed6a43;
}

.markdown-body .pl-id {
  color: #b52a1d;
}

.markdown-body .pl-ii {
  background-color: #b52a1d;
  color: #f8f8f8;
}

.markdown-body .pl-sr .pl-cce {
  color: #63a35c;
  font-weight: bold;
}

.markdown-body .pl-ml {
  color: #693a17;
}

.markdown-body .pl-mh,
.markdown-body .pl-mh .pl-en,
.markdown-body .pl-ms {
  color: #1d3e81;
  font-weight: bold;
}

.markdown-body .pl-mq {
  color: #008080;
}

.markdown-body .pl-mi {
  color: #333;
  font-style: italic;
}

.markdown-body .pl-mb {
  color: #333;
  font-weight: bold;
}

.markdown-body .pl-md {
  background-color: #ffecec;
  color: #bd2c00;
}

.markdown-body .pl-mi1 {
  background-color: #eaffea;
  color: #55a532;
}

.markdown-body .pl-mdr {
  color: #795da3;
  font-weight: bold;
}

.markdown-body .pl-mo {
  color: #1d3e81;
}

.markdown-body kbd {
  display: inline-block;
  padding: 3px 5px;
  font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace;
  line-height: 10px;
  color: #555;
  vertical-align: middle;
  background-color: #fcfcfc;
  border: solid 1px #ccc;
  border-bottom-color: #bbb;
  border-radius: 3px;
  box-shadow: inset 0 -1px 0 #bbb;
}

.markdown-body .plan-price-unit {
  color: #767676;
  font-weight: normal;
}

.markdown-body .task-list-item {
  list-style-type: none;
}

.markdown-body .task-list-item+.task-list-item {
  margin-top: 3px;
}

.markdown-body .task-list-item input {
  margin: 0 0.35em 0.25em -1.6em;
  vertical-align: middle;
}

.markdown-body .plan-choice {
  padding: 15px;
  padding-left: 40px;
  display: block;
  border: 1px solid #e0e0e0;
  position: relative;
  font-weight: normal;
  background-color: #fafafa;
}

.markdown-body .plan-choice.open {
  background-color: #fff;
}

.markdown-body .plan-choice.open .plan-choice-seat-breakdown {
  display: block;
}

.markdown-body .plan-choice-free {
  border-radius: 3px 3px 0 0;
}

.markdown-body .plan-choice-paid {
  border-radius: 0 0 3px 3px;
  border-top: 0;
  margin-bottom: 20px;
}

.markdown-body .plan-choice-radio {
  position: absolute;
  left: 15px;
  top: 18px;
}

.markdown-body .plan-choice-exp {
  color: #999;
  font-size: 12px;
  margin-top: 5px;
}

.markdown-body .plan-choice-seat-breakdown {
  margin-top: 10px;
  display: none;
}

.markdown-body :checked+.radio-label {
  z-index: 1;
  position: relative;
  border-color: #4078c0;
}

@media print {
  body .markdown-body {
    padding: 0;
    border: none;
  }
}
</style><title>README</title></head><body><article class="markdown-body"><h1>
<a id="user-content-vue-shiyanlou" class="anchor" href="#vue-shiyanlou" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>vue-shiyanlou</h1>
<p>啊哈！ (〃'▽'〃)</p>
<p>用Vue实现的非官方实验楼整站，用于学习交流。</p>
<p>选择实验楼原因也很简单：实验楼的设计个人很喜欢，简单鲜明一目了然，但实际用<code>CSS</code>实现起来又不乏一些“高级”用法，动画，过渡，纯<code>CSS</code>小箭头等等都可以从实验楼的源码中学习到。前后端分离通过一步步分析API慢慢搭建出整个页面的过程仿佛真的参与其中，抓取API分析HTTP，处理登录逻辑，筛选课程，购买课程，发帖回帖参与讨论等等都可以慢慢从中抽丝剥茧般的熟悉起来。</p>
<p>目前已实现90%的页面, 登录，选课，设置个人信息，发帖，回帖，评论，报告，看教程等等都已实现，全部实验楼官方API，真实数据。</p>
<h1>
<a id="user-content-技术栈" class="anchor" href="#%E6%8A%80%E6%9C%AF%E6%A0%88" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>技术栈</h1>
<pre><code>vue2 + vuex + vue-router + axios + webpack + ES6/7 + flex
</code></pre>
<h1>
<a id="user-content-项目运行本地" class="anchor" href="#%E9%A1%B9%E7%9B%AE%E8%BF%90%E8%A1%8C%E6%9C%AC%E5%9C%B0" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>项目运行(本地)</h1>
<pre><code>git clone git@github.com:HuberTRoy/vue-shiyanlou.git

cd vue-shiyanlou

npm install

npm run dev
</code></pre>
<h1>
<a id="user-content-关于接口数据" class="anchor" href="#%E5%85%B3%E4%BA%8E%E6%8E%A5%E5%8F%A3%E6%95%B0%E6%8D%AE" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>关于接口数据</h1>
<pre><code>实验楼API不能跨域,需要再写一个代理。
用Django写了个简单的后端转发。
没有API的话是没有数据可以展示的呦~。
</code></pre>
<p><a href="https://github.com/HuberTRoy/vue-shiyanlou-backend">代理请求API后端</a></p>
<h1>
<a id="user-content-说明" class="anchor" href="#%E8%AF%B4%E6%98%8E" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>说明</h1>
<blockquote>
<p>如果对您有帮助，希望可以得到一枚您的Star~。(〃'▽'〃)</p>
</blockquote>
<blockquote>
<p>有任何可以改进的地方希望您可以花费一些时间开启一个Issue或者直接PR~。φ(&gt;ω&lt;*)</p>
</blockquote>
<blockquote>
<p>目前没有线上演示。(￣.￣)</p>
</blockquote>
<h1>
<a id="user-content-总结" class="anchor" href="#%E6%80%BB%E7%BB%93" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>总结</h1>
<ol>
<li>自己想要学习前端，看到Vue框架比较火热，上手简单功能也很强大于是学习了起来，无奈的是搜索到的项目大部分都比较简单，不是TODO就是音乐播放器，逻辑没有想象中的复杂。(；´д｀)ゞ</li>
<li>在 Github 搜索时看到大佬用 Vue 写的饿了么应用，于是自己也想试试实现一个这样的应用。(o°ω°o)</li>
<li>实验楼的编程课在初学时很友好，界面自己也很喜欢。慢慢模仿下来如在里面学习一样，页面逻辑刚开始会简单些，学习<code>HTML,CSS</code>基础就可以摸索着写出来，随着越来越多的内容，动画，过渡也慢慢浮现出来，同时处理登录，查看状态，绑定邮箱，发布内容，参与讨论等等一系列逻辑复杂的东西也进入眼帘。╮(￣▽￣)╭</li>
<li>整个项目从<code>vue-cli</code>自动生成开始，未配置任何东西，直接上手就开始写了，跟随<code>commit</code>的话可以找到各种初学时可能会犯的错误以及未注意到的地方，比如一开始没有用<code>CSS</code>框架，也没有统一的<code>CSS</code>文件归类，导致每个组件里越写重复的越多，之后才恍然大悟，喔...<code>class</code>和框架的作用原来是这样用的，但同时也通过这样全部都写的原生<code>CSS</code>得以一窥<code>CSS</code>真容。｡◕ᴗ◕｡</li>
<li>项目初步已经完成，包括子页面在内有20+个页面，完全独立的页面有16个，可以抓取到的API有46个，配合后端的API转发可以得到实验楼真实数据，进行真实交互。ヽ(•ω•ゞ)</li>
<li>项目还有大量可以优化的地方，并未完全完成。(￣▽￣)／</li>
</ol>
<h1>
<a id="user-content-部分截图" class="anchor" href="#%E9%83%A8%E5%88%86%E6%88%AA%E5%9B%BE" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>部分截图</h1>
<h2>
<a id="user-content-首页" class="anchor" href="#%E9%A6%96%E9%A1%B5" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>首页</h2>
<p><a href="https://github.com/HuberTRoy/vue-shiyanlou/blob/master/screenshots/index/index1.png" target="_blank" rel="noopener noreferrer"><img src="https://github.com/HuberTRoy/vue-shiyanlou/raw/master/screenshots/index/index1.png" alt="首页1" style="max-width:100%;"></a>
<a href="https://github.com/HuberTRoy/vue-shiyanlou/blob/master/screenshots/index/index2.png" target="_blank" rel="noopener noreferrer"><img src="https://github.com/HuberTRoy/vue-shiyanlou/raw/master/screenshots/index/index2.png" alt="首页2" style="max-width:100%;"></a></p>
<h2>
<a id="user-content-课程" class="anchor" href="#%E8%AF%BE%E7%A8%8B" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>课程</h2>
<p><a href="https://github.com/HuberTRoy/vue-shiyanlou/blob/master/screenshots/courses/1.png" target="_blank" rel="noopener noreferrer"><img src="https://github.com/HuberTRoy/vue-shiyanlou/raw/master/screenshots/courses/1.png" alt="课程1" style="max-width:100%;"></a>
<a href="https://github.com/HuberTRoy/vue-shiyanlou/blob/master/screenshots/courses/2.png" target="_blank" rel="noopener noreferrer"><img src="https://github.com/HuberTRoy/vue-shiyanlou/raw/master/screenshots/courses/2.png" alt="课程2" style="max-width:100%;"></a></p>
<h2>
<a id="user-content-社区讨论" class="anchor" href="#%E7%A4%BE%E5%8C%BA%E8%AE%A8%E8%AE%BA" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>社区讨论</h2>
<p><a href="https://github.com/HuberTRoy/vue-shiyanlou/blob/master/screenshots/questions/1.png" target="_blank" rel="noopener noreferrer"><img src="https://github.com/HuberTRoy/vue-shiyanlou/raw/master/screenshots/questions/1.png" alt="社区1" style="max-width:100%;"></a>
<a href="https://github.com/HuberTRoy/vue-shiyanlou/blob/master/screenshots/questions/2.png" target="_blank" rel="noopener noreferrer"><img src="https://github.com/HuberTRoy/vue-shiyanlou/raw/master/screenshots/questions/2.png" alt="社区2" style="max-width:100%;"></a>
<a href="https://github.com/HuberTRoy/vue-shiyanlou/blob/master/screenshots/questions/3.png" target="_blank" rel="noopener noreferrer"><img src="https://github.com/HuberTRoy/vue-shiyanlou/raw/master/screenshots/questions/3.png" alt="社区3" style="max-width:100%;"></a></p>
<h1>
<a id="user-content-目标" class="anchor" href="#%E7%9B%AE%E6%A0%87" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>目标</h1>
<p>TODO 前端部分</p>
<ul>
<li>[x] 主页</li>
<li>[x] 课程挑选页</li>
<li>[x] 具体课程页</li>
<li>[x] 路径页</li>
<li>[x] 具体路径页</li>
<li>[x] 社区讨论页</li>
<li>[x] 社区具体问题页</li>
<li>[x] 帖子编辑页。</li>
<li>[ ] 用户页面
<ul>
<li>[x] 登录栏</li>
<li>[x] 导航栏</li>
<li>[x] 课程与路径页编辑框</li>
<li>[x] question出现编辑框</li>
<li>[X] 继续实验</li>
<li>[x] user/id
self 标志为仅自己可见
<ul>
<li>[x] user/id (总览)
<ul>
<li>[x] 基础信息</li>
<li>[x] 学习卡片 (self)</li>
<li>[x] 学习记录(热点图)</li>
<li>[x] 下列子应用</li>
<li>[x] 最近来访</li>
</ul>
</li>
<li>[ ] user/id/courses
<ul>
<li>[x] 历史学习</li>
<li>[x] 关注的</li>
<li>[ ] 发布的</li>
</ul>
</li>
<li>[x] user/id/learning_path</li>
<li>[x] user/id/reports</li>
<li>[x] user/id/discuss</li>
<li>[ ] user/id/contest ( self )</li>
<li>[ ] user/id/tutorial ( self )</li>
<li>[ ] user/id/software ( self )</li>
<li>[ ] user/id/messages ( self )</li>
</ul>
</li>
</ul>
</li>
<li>[x] 用户信息设置页
<ul>
<li>[x] 基础信息设置</li>
<li>[x] 账号密码设置</li>
<li>[x] 邮件通知设置</li>
<li>[x] 兑换码</li>
</ul>
</li>
<li>[x] 搜索页</li>
<li>[x] 404页</li>
<li>[x] 教程页</li>
<li>[x] 独立的登录注册页</li>
<li>[x] 报告总览页</li>
<li>[x] 报告详情页</li>
<li>[x] Markdown 编辑器。
<ul>
<li>[x] 基础功能(加粗,斜线,链接...)</li>
<li>[x] 编辑后预览</li>
<li>[x] 上传图片</li>
</ul>
</li>
<li>[ ] 楼+页(待定)</li>
<li>[ ] 会员页(待定)</li>
</ul>
<p>TODO 后端(代理)配合部分</p>
<ul>
<li>[x] 对接登陆.</li>
<li>[x] 对接主页API.
<ul>
<li>[x] 轮播图。</li>
<li>[x] 课程分类/推荐。</li>
<li>[x] 楼+推荐。</li>
<li>[x] 路径。</li>
</ul>
</li>
<li>[ ] 对接课程页API.
<ul>
<li>[x] 课程挑选。</li>
<li>[x] 课程信息。</li>
<li>[x] 课程状态。</li>
<li>[x] 课程评论/报告/问答。</li>
<li>[x] 关注/取消关注。</li>
<li>[x] 加入课程/继续学习。</li>
<li>[ ] 相关课程推荐(暂时找不到相关API)</li>
</ul>
</li>
<li>[x] 对接路径页API.
<ul>
<li>[x] 路径总览。</li>
<li>[x] 路径信息。</li>
<li>[x] 路径评论。</li>
<li>[x] 加入路径。</li>
</ul>
</li>
<li>[x] 对接问答区API.
<ul>
<li>[x] 发帖。</li>
<li>[x] 回帖。</li>
<li>[x] 签到。</li>
</ul>
</li>
<li>[x] 各区域回复.</li>
<li>[x] 各区域删除.</li>
<li>[x] 对接用户主页API.
<ul>
<li>[x] 基础信息。</li>
<li>[x] 课程信息。</li>
<li>[x] 路径信息。</li>
<li>[x] 报告信息。</li>
<li>[x] 问答信息。</li>
</ul>
</li>
<li>[x] 修改个人信息。
<ul>
<li>[x] 修改基础信息。</li>
<li>[x] 上传头像(上传到实验楼)。</li>
<li>[x] 修改邮件通知。</li>
<li>[x] 修改/绑定手机/邮箱/密码。</li>
</ul>
</li>
<li>[x] 搜索API。</li>
<li>[x] 教程区API。</li>
<li>[x] 报告总览API。</li>
<li>[x] 报告详情API。</li>
</ul>
<p>细节优化:</p>
<ul>
<li>[ ] 多分辨率支持。</li>
<li>[ ] <code>CSS</code>优化, 目前有很多重复，而且分布在每个component里。</li>
<li>[ ] <code>route</code>优化, 加入切换动画使其更加平滑切换。</li>
<li>[ ] 细微处1px优化。</li>
</ul>
<h1>
<a id="user-content-目录结构" class="anchor" href="#%E7%9B%AE%E5%BD%95%E7%BB%93%E6%9E%84" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>目录结构</h1>
<pre><code>api                           存放各类需要与后端交互获取数据的api   
    courses   
        course_information    获取某一个课程的信息。   
        courses_content       获取出合适的所有课程，适用于courses_selections中的大分类获取。 
        course_comment        课程评论
        course_qa             课程问答
        course_report         课程报告
    home
        home                  主页内容
    logged_info
        logged_info           登录后才会解锁的内容(用户课程信息获取) 
    login
        login                 登录和获取登录成功后的用户信息。
    path                      
        course_path           某个路径的具体信息
        course_path_comment   路径评论
        path                  所有路径的简介
    questions
        questions             请求所有问题的api
        question              请求查看具体问题的api
    related_stuff
        related_stuff         获取近期活动/楼+信息。
    user
        user                  获取用户主页下的各类用户信息。
    base.js                   配置api域名等基础信息。

sotre                         vuex进行数据流控制的仓库  
   modules  
      course                  具体课程的信息仓库。  
      courses_category        课程主页的分类仓库  
          courses_category    里面包含各个query的state设置，更改与变化后的路由导向与触发数据请求。
      home                    主页信息仓库。
      logged_info             用户学习过的课程的信息仓库。
      login_state             包含所有与登录有关信息。
      path                    包含路径部分的状态信息。
      questions               包含所有与社区问题讨论有关的状态信息。
      scroll_bar  
          scroll_bar          包含是否正在向下滚动，是否不处于顶层，是否在向上滚动。  
      tab_page                暂时无用。
      user                    用户主页信息仓库。

components  
    common_components          项目中会在多个页面中用到的公共子组件
       footer
           footer              版权导航信息
       scroll_bar              一个会随着滚动的顶部导航，包括注册，搜索，跳转到主要的分类区。
           scroll_bar
       cards                   不同的小的选项卡，提供多种不同的效果。
           card                普通的card，盛放一个可设置跳转链接的img。
           card_plus           普通card的加强版，放置有一个可设置跳转链接的img和text。
           lou_plus_card       楼+部分的card。
           float_card          一个带有鼠标悬停时会向上略微浮动动画的card_plus
           courses_card        课程card分为：背景img，标题，介绍和 参与人数与课程类型(免费，训练营，会员和无)，课程介绍会在无访问时隐藏，访问时由下至上出现，一个动画实现。
           traning_card        算是上面课程card的扩展实现，取消动画，取而代之的是由更大的占地面积直接铺出来。
           ...
       sign_on_up              触发登陆和注册页面的组件。
            login              包含登陆和注册组件
            sign_on            登陆组件
            sign_up            注册组件  
       qa_item                 问答组件。
       report_item             报告组件。
       loading                 loading组件。

    home_page  
       // 查阅pages中的信息   
       ...   
    
    courses_page   
       // 查阅pages中的信息   
       ...   
    
    path_page
       // 查阅pages中的信息
       ...

    questions
       // 查阅pages中的信息
       ...

    user_page
       // 查阅pages中的信息
       ...

pages       
    home                                   实验楼主页
       navigation                          顶部导航栏
           -- other                           子组件
       main_course                         依然是导航栏，分布的是主要的课程分类和广告
           -- other   
       luoplus                             楼+的课程推广
       kindsOfCourses                      其他各类课程的推广 基础/精选/大数据 等等
       footer                              最后的底部导航版权信息等   
    courses                                课程页面
        sub_components
          order_button
          selection_button
          tab_page
        course
          sub_components
            course_discuss_sub_components/ 课程讨论部分的子组件

            course_content                 课程主内容
            course_description             课程长简介
            course_discuss                 课程讨论部分 包括评论/报告/问答。
            course_header_bar              下拉时出现的课程基础信息导航。
            course_knowledge_point         课程主要学习点
            course_related                 相关课程
            course_side_content            课程区右侧会出现的内容
            course_teacher                 课程教师信息
            nav_title                      课程基础信息+导航
    path
        path                               所有路径页面
        sub_components/
          paths                                                 
          title                            所有路径页面下的子组件。
        course_path/
          course_path                      某个路径的信息页。
          sub_components/
            nav_title                      基础信息+导航
            path_course_detail             路径详情。
            path_description               路径简介。
            path_operation                 路径操作面板(加入路径)。
            related_items                  相关的一些信息
    questions                              讨论页面
      questions                            所有问题的主页
      sub_compoents/
        main_questions                     问答区。
        side                               其他的一些工具(发帖签到相关内容等)。
        main_questions_sub_components/
          nav_bar                          基础信息+导航
          question_list                    问题列表盒子。
          tab_page                         翻页组件。
        side_sub_components/               
          ...
      question/
        question                           具体问答页。
        sub_components/
          main_question                    具体问答页主体。
          side                             其他的一些工具(相关帖子等)
          main_question_sub_components/
            nav_bar                        基础信息+导航
            question_content               问题的主体。
            question_reply                 问题的回复(包括回帖/翻页)。
    user                       
        user                               用户界面总页面
        sub_components/
          base_info                        基础信息
          learning_card                    学习卡
          learning_record                  学习记录热点图
          stuff_board                      各类信息包括课程/讨论/报告/教程...
          visited_user                     访问过的用户

</code></pre>
</article></body></html>